package com.easylinkin.linkappapi.common.translate;

import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONUtil;
import com.easylinkin.linkappapi.security.entity.LinkappUser;
import com.easylinkin.linkappapi.security.mapper.LinkappUserMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 用户名翻译器
 * 负责将用户ID翻译为用户名，支持本地缓存以提高性能
 *
 * @author OYGD
 */
@Slf4j
@Component
@Lazy(false)
public class UserNameTranslator implements CodeTranslateor {

    /** 本地缓存，用于快速访问 */
    private static final Map<String, String> LOCAL_CACHE = new ConcurrentHashMap<>();

    /** 缓存过期时间（毫秒） */
    private static final long CACHE_EXPIRE_TIME = 5 * 60 * 1000; // 5分钟

    /** 上次清理缓存的时间 */
    private static long lastClearTime = System.currentTimeMillis();

    /** 系统用户ID */
    private static final String SYSTEM_USER_ID = "-1";

    /** 系统用户名 */
    private static final String SYSTEM_USER_NAME = "系统";

    static UserNameTranslator trans;

    @Autowired
    private LinkappUserMapper linkappUserMapper;

    public UserNameTranslator() {
        trans = this;
        CodeTranslateorFactory.register(this.getClass(), this);
    }

    /**
     * 设置用户名到本地缓存
     *
     * @param userId 用户ID
     * @param name   用户名
     */
    public static void set(String userId, String name) {
        if (StrUtil.isNotBlank(userId) && StrUtil.isNotBlank(name)) {
            LOCAL_CACHE.put(userId, name);
        }
    }

    /**
     * 从本地缓存中删除用户名
     *
     * @param userId 用户ID
     */
    public static void remove(String userId) {
        if (StrUtil.isNotBlank(userId)) {
            LOCAL_CACHE.remove(userId);
        }
    }

    /**
     * 从数据库查询用户名
     *
     * @param userId 用户ID
     * @return 用户名，查询失败返回空字符串
     */
    private static String getUserNameFromDatabase(String userId) {
        if (StrUtil.isBlank(userId)) {
            return "";
        }

        try {
            Long id = Long.valueOf(userId);
            LinkappUser user = trans.linkappUserMapper.selectById(id);
            if (user != null) {
                // 优先返回nickname，如果为空则返回username
                String name = StrUtil.isNotBlank(user.getNickname()) ? user.getNickname() : user.getUsername();
                return StrUtil.isNotBlank(name) ? name : "";
            }
        } catch (NumberFormatException e) {
            log.warn("用户ID格式错误，userId: {}", userId);
        } catch (Exception e) {
            log.error("查询用户名失败，userId: {}, error: {}", userId, e.getMessage(), e);
        }
        return "";
    }

    /**
     * 检查并清理过期缓存
     */
    private static void checkAndClearCache() {
        long currentTime = System.currentTimeMillis();
        if (currentTime - lastClearTime > CACHE_EXPIRE_TIME) {
            log.debug("清理用户名本地缓存，缓存大小：{}", LOCAL_CACHE.size());
            LOCAL_CACHE.clear();
            lastClearTime = currentTime;
        }
    }

    /**
     * 翻译用户ID为用户名
     *
     * @param obj   对象（未使用）
     * @param value 用户ID
     * @return 用户名
     */
    public static String translate(Object obj, Object value) {
        if (value == null) {
            return "";
        }

        // 检查并清理缓存
        checkAndClearCache();

        String userId = value.toString();

        // 处理系统用户
        if (SYSTEM_USER_ID.equals(userId)) {
            return SYSTEM_USER_NAME;
        }

        // 先查本地缓存
        String cachedName = LOCAL_CACHE.get(userId);
        if (cachedName != null) {
            return cachedName;
        }

        // 查数据库
        String name = getUserNameFromDatabase(userId);
        if (StrUtil.isNotBlank(name)) {
            // 放入本地缓存
            LOCAL_CACHE.put(userId, name);
            return name;
        }
        return "";
    }

    /**
     * 静态翻译方法，支持多种数据类型
     *
     * @param obj   对象（未使用）
     * @param value 待翻译的值
     * @param ann   注解配置
     * @return 翻译结果
     */
    public static String translateStatic(Object obj, Object value, Code2Text ann) {
        if (value == null) {
            return null;
        }

        // 检查并清理缓存
        checkAndClearCache();

        // 处理系统用户
        if (SYSTEM_USER_ID.equals(value.toString())) {
            return SYSTEM_USER_NAME;
        }

        // 处理List类型
        if (value instanceof List) {
            return translateList((List<?>) value);
        }

        // 处理分割类型
        if (ann.type() == TypeEnum.SPILT) {
            return translateSplitValue(value.toString());
        }

        // 处理单个值
        return translateSingleValue(value.toString());
    }

    /**
     * 翻译List类型的用户ID集合
     *
     * @param userIdList 用户ID列表
     * @return 用户名列表，用逗号分隔
     */
    private static String translateList(List<?> userIdList) {
        List<String> nameList = new ArrayList<>(userIdList.size());
        for (Object item : userIdList) {
            if (item != null) {
                String name = translateSingleValue(item.toString());
                if (StrUtil.isNotBlank(name)) {
                    nameList.add(name);
                }
            }
        }
        return StrUtil.join("，", nameList);
    }
    /**
     * 翻译分割类型的值（JSON数组或逗号分隔字符串）
     *
     * @param strVal 字符串值
     * @return 翻译结果
     */
    private static String translateSplitValue(String strVal) {
        if (JSONUtil.isJsonArray(strVal)) {
            return translateJsonArray(strVal);
        } else {
            return translateCommaSeparatedString(strVal);
        }
    }

    /**
     * 翻译JSON数组格式的用户ID
     *
     * @param jsonStr JSON数组字符串
     * @return 用户名列表，用逗号分隔
     */
    private static String translateJsonArray(String jsonStr) {
        try {
            JSONArray array = JSONUtil.parseArray(jsonStr);
            List<String> nameList = new ArrayList<>(array.size());
            for (Object item : array) {
                if (item != null) {
                    String name = translateSingleValue(item.toString());
                    if (StrUtil.isNotBlank(name)) {
                        nameList.add(name);
                    }
                }
            }
            return StrUtil.join("，", nameList);
        } catch (Exception e) {
            log.error("解析JSON数组失败，jsonStr: {}, error: {}", jsonStr, e.getMessage(), e);
            return "";
        }
    }

    /**
     * 翻译逗号分隔的用户ID字符串
     *
     * @param commaSeparatedStr 逗号分隔的字符串
     * @return 用户名列表，用逗号分隔
     */
    private static String translateCommaSeparatedString(String commaSeparatedStr) {
        String[] userIds = commaSeparatedStr.split(",");
        List<String> nameList = new ArrayList<>(userIds.length);
        for (String userId : userIds) {
            if (StrUtil.isNotBlank(userId)) {
                String name = translateSingleValue(userId.trim());
                if (StrUtil.isNotBlank(name)) {
                    nameList.add(name);
                }
            }
        }
        return StrUtil.join("，", nameList);
    }

    /**
     * 翻译单个用户ID
     *
     * @param userId 用户ID
     * @return 用户名
     */
    private static String translateSingleValue(String userId) {
        if (StrUtil.isBlank(userId)) {
            return "";
        }

        // 处理系统用户
        if (SYSTEM_USER_ID.equals(userId)) {
            return SYSTEM_USER_NAME;
        }

        // 先查本地缓存
        String cachedName = LOCAL_CACHE.get(userId);
        if (cachedName != null) {
            return cachedName;
        }

        // 查数据库
        String name = getUserNameFromDatabase(userId);
        if (StrUtil.isNotBlank(name)) {
            // 放入本地缓存
            LOCAL_CACHE.put(userId, name);
            return name;
        }
        return "";
    }

    @Override
    public String translate(Object obj, Object value, Code2Text ann) {
        if (value == null) {
            return null;
        }
        return translateStatic(obj, value, ann);
    }

}
